use std::collections::{BTreeMap, HashMap};
use std::fmt::Formatter;
use std::path::Path;
use serde::{Deserialize, Deserializer,de::Visitor};
use serde::de::MapAccess;

#[derive(Debug)]
struct District {
    citys:Vec<(String,Vec<String>)>,
}
pub fn count_provinces() -> String {
    let mut output = String::new();
    let mut citymap:HashMap<String,usize> = HashMap::new();
    let mut code:usize;
    let mut maxcode:usize;
    let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
    let district_path = Path::new(&dir).join("district.json");
    let file = std::fs::File::open(district_path).unwrap();
    let disstricts:BTreeMap<u64,District> = serde_json::from_reader(file).unwrap();
    for citys in disstricts.values() {
        maxcode=0;
        for (key,value) in citys.citys.iter() {
            code=0;
            match citymap.get(key) {
                None => {}
                Some(c) => {code=c.clone();}
            }
            for v in value.iter() {
                match citymap.get(v) {
                    None => {}
                    Some(c) => {code=c.clone();break;}
                }
            }
            if code==0 {
                maxcode=maxcode+1;
                code=maxcode;
            }
            citymap.insert(key.clone(),code.clone());
            for value in value.iter() {
                citymap.insert(value.clone(),code.clone());
            }
        }
        output.push_str(&maxcode.to_string());
        output.push(',');
        citymap.clear();
    }
    output.pop();
    output
}
impl<'de> Deserialize<'de> for District {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>
    {
        deserializer.deserialize_map(DistricVisitor)
    }
}
struct DistricVisitor;
impl<'de> Visitor<'de> for DistricVisitor {
    type Value = District;

    fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
        formatter.write_str("no map")
    }

    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
    where
        A: MapAccess<'de>
    {
        let mut myvec: Vec<(String,Vec<String>)>= Vec::new();
        while let Some((key, value)) = map.next_entry()? {
            myvec.push((key,value));
        }
        Ok(District { citys: myvec })
    }
}
